iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 21
0

Description:
這demo是實作一個側邊欄,側邊欄是非常常用的一種功能。使用者可以點選按鈕來展開 / 收起側邊欄。


Component:

  1. NavigationController
  2. UIView
  3. UICollectionView

Highlight function:
先於navigationItem 加上左鍵及按下後的動作:

let leftBtn = UIBarButtonItem(image: UIImage(named:"hamburger"),
                              style: .plain,
                              target: self,
                              action: #selector(HomeController.leftBarBtnAct))
self.navigationItem.leftBarButtonItem = leftBtn

@IBAction func leftBarBtnAct() {
  settingLancher.showSetting()
}

在demo中按下顯示側邊欄按鈕時,主畫面會稍微變黑,其方法是透過疊加上一層 UIView 後並改變其背景 alpha 值來達成:

let backView = UIView()
backView.backgroundColor = UIColor(white: 0, alpha: 0.5)

接下來用 UICollectionView 來設計按下按鍵後會滑出的側邊欄,此原理其實是將會滑進主畫面之側邊欄先放置於超出主畫面的位置(假設側邊欄寬度為 140,那預設位置的 X 軸為 -140),在透過按鈕動畫來將側邊欄滑出。

func showSetting() {
  if let window = UIApplication.shared.keyWindow {
      
    let collYPossion = statusBarHeight() + naviBarHeight()
    collectView.frame = CGRect(x: -(window.frame.width / 3),
                               y: collYPossion,
                               width: window.frame.width / 3,
                               height: window.frame.height - collYPossion - 10)
    window.addSubview(collectView)
      
    UIView.animate(withDuration: 1.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
      self.backView.alpha = 1
      self.collectView.frame = CGRect(x: 0,
                                      y: collYPossion,
                                      width: window.frame.width / 3,
                                      height: window.frame.height - collYPossion)
    }, completion: nil)  
  }
}

透過動畫做好滑出側邊欄的行為後,還需要實作使用者點選畫面後隱藏側邊欄之手勢功能。

func showSetting() {
  backView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
}

@IBAction func handleDismiss(setting: Setting) {
  UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
    self.backView.alpha = 0
      
    if let window = UIApplication.shared.keyWindow {
      let collYPossion = self.statusBarHeight() + self.naviBarHeight()
      self.collectView.frame = CGRect(x: -(window.frame.width / 3),
                                      y: collYPossion,
                                      width: window.frame.width / 3,
                                      height: window.frame.height - collYPossion)
    }
  }) { (completed: Bool) in }
}

Reference:
Source code on Github


上一篇
iOS App 實作(15) Local UserNotifications
下一篇
iOS App 實作(17) Shake Detect
系列文
30天Swift入門學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
陳董粉絲
iT邦新手 5 級 ‧ 2018-01-11 13:53:55

func showSetting() {
backView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
}
==> 這一段是不是貼錯了 你重覆定義了 showSetting() ?

@IBAction func handleDismiss(setting: Setting)
==> 基本上你有定義 UITapGestureRecognizer(target: self, action: #selector(handleDismiss) 經由tap觸發傳進來的參數會是 UIGestureRecognizer型態 不會是Setting

吳晉榮 iT邦新手 5 級 ‧ 2018-01-12 11:57:30 檢舉
  1. showSetting() 並沒有被重複定義
  2. 傳 setting 這 parameter 本來是有其他用途但後來被我拿掉了
  1. 我是要提醒這種寫法complie不會出錯 但是你實際操作結果可能不會是你預期的 你可以把你source code mask掉那幾行改回來然後用點的dismiss

我要留言

立即登入留言